home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / EXAMPLES / glutplane.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  5.7 KB  |  271 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1994. */
  3.  
  4. /* This program is freely distributable without licensing fees 
  5.    and is provided without guarantee or warrantee expressed or 
  6.    implied. This program is -not- in the public domain. */
  7.  
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #ifndef _WIN32
  11. #include <unistd.h>
  12. #else
  13. #include <process.h>  /* for getpid */
  14. #define random rand
  15. #define srandom srand
  16. #endif
  17. #include <math.h>
  18. #include <GL/glut.h>
  19.  
  20. /* Some <math.h> files do not define M_PI... */
  21. #ifndef M_PI
  22. #define M_PI 3.14159265358979323846
  23. #endif
  24. #ifndef M_PI_2
  25. #define M_PI_2 1.57079632679489661923
  26. #endif
  27.  
  28. GLboolean moving = GL_FALSE;
  29.  
  30. #define MAX_PLANES 15
  31.  
  32. struct {
  33.   float speed;          /* zero speed means not flying */
  34.   GLfloat red, green, blue;
  35.   float theta;
  36.   float x, y, z, angle;
  37. } planes[MAX_PLANES];
  38.  
  39. #define v3f glVertex3f  /* v3f was the short IRIS GL name for
  40.                            glVertex3f */
  41.  
  42. void
  43. draw(void)
  44. {
  45.   GLfloat red, green, blue;
  46.   int i;
  47.  
  48.   glClear(GL_DEPTH_BUFFER_BIT);
  49.   /* paint black to blue smooth shaded polygon for background */
  50.   glDisable(GL_DEPTH_TEST);
  51.   glShadeModel(GL_SMOOTH);
  52.   glBegin(GL_POLYGON);
  53.   glColor3f(0.0, 0.0, 0.0);
  54.   v3f(-20, 20, -19);
  55.   v3f(20, 20, -19);
  56.   glColor3f(0.0, 0.0, 1.0);
  57.   v3f(20, -20, -19);
  58.   v3f(-20, -20, -19);
  59.   glEnd();
  60.   /* paint planes */
  61.   glEnable(GL_DEPTH_TEST);
  62.   glShadeModel(GL_FLAT);
  63.   for (i = 0; i < MAX_PLANES; i++)
  64.     if (planes[i].speed != 0.0) {
  65.       glPushMatrix();
  66.       glTranslatef(planes[i].x, planes[i].y, planes[i].z);
  67.       glRotatef(290.0, 1.0, 0.0, 0.0);
  68.       glRotatef(planes[i].angle, 0.0, 0.0, 1.0);
  69.       glScalef(1.0 / 3.0, 1.0 / 4.0, 1.0 / 4.0);
  70.       glTranslatef(0.0, -4.0, -1.5);
  71.       glBegin(GL_TRIANGLE_STRIP);
  72.       /* left wing */
  73.       v3f(-7.0, 0.0, 2.0);
  74.       v3f(-1.0, 0.0, 3.0);
  75.       glColor3f(red = planes[i].red, green = planes[i].green,
  76.         blue = planes[i].blue);
  77.       v3f(-1.0, 7.0, 3.0);
  78.       /* left side */
  79.       glColor3f(0.6 * red, 0.6 * green, 0.6 * blue);
  80.       v3f(0.0, 0.0, 0.0);
  81.       v3f(0.0, 8.0, 0.0);
  82.       /* right side */
  83.       v3f(1.0, 0.0, 3.0);
  84.       v3f(1.0, 7.0, 3.0);
  85.       /* final tip of right wing */
  86.       glColor3f(red, green, blue);
  87.       v3f(7.0, 0.0, 2.0);
  88.       glEnd();
  89.       glPopMatrix();
  90.     }
  91.   glutSwapBuffers();
  92. }
  93.  
  94. void
  95. tick_per_plane(int i)
  96. {
  97.   float theta = planes[i].theta += planes[i].speed;
  98.   planes[i].z = -9 + 4 * cos(theta);
  99.   planes[i].x = 4 * sin(2 * theta);
  100.   planes[i].y = sin(theta / 3.4) * 3;
  101.   planes[i].angle = ((atan(2.0) + M_PI_2) * sin(theta) - M_PI_2) * 180 / M_PI;
  102.   if (planes[i].speed < 0.0)
  103.     planes[i].angle += 180;
  104. }
  105.  
  106. void
  107. add_plane(void)
  108. {
  109.   int i;
  110.  
  111.   for (i = 0; i < MAX_PLANES; i++)
  112.     if (planes[i].speed == 0) {
  113.  
  114. #define SET_COLOR(r,g,b) \
  115.     planes[i].red=r; planes[i].green=g; planes[i].blue=b;
  116.  
  117.       switch (random() % 6) {
  118.       case 0:
  119.         SET_COLOR(1.0, 0.0, 0.0);  /* red */
  120.         break;
  121.       case 1:
  122.         SET_COLOR(1.0, 1.0, 1.0);  /* white */
  123.         break;
  124.       case 2:
  125.         SET_COLOR(0.0, 1.0, 0.0);  /* green */
  126.         break;
  127.       case 3:
  128.         SET_COLOR(1.0, 0.0, 1.0);  /* magenta */
  129.         break;
  130.       case 4:
  131.         SET_COLOR(1.0, 1.0, 0.0);  /* yellow */
  132.         break;
  133.       case 5:
  134.         SET_COLOR(0.0, 1.0, 1.0);  /* cyan */
  135.         break;
  136.       }
  137.       planes[i].speed = ((float) (random() % 20)) * 0.001 + 0.02;
  138.       if (random() & 0x1)
  139.         planes[i].speed *= -1;
  140.       planes[i].theta = ((float) (random() % 257)) * 0.1111;
  141.       tick_per_plane(i);
  142.       if (!moving)
  143.         glutPostRedisplay();
  144.       return;
  145.     }
  146. }
  147.  
  148. void
  149. remove_plane(void)
  150. {
  151.   int i;
  152.  
  153.   for (i = MAX_PLANES - 1; i >= 0; i--)
  154.     if (planes[i].speed != 0) {
  155.       planes[i].speed = 0;
  156.       if (!moving)
  157.         glutPostRedisplay();
  158.       return;
  159.     }
  160. }
  161.  
  162. void
  163. tick(void)
  164. {
  165.   int i;
  166.  
  167.   for (i = 0; i < MAX_PLANES; i++)
  168.     if (planes[i].speed != 0.0)
  169.       tick_per_plane(i);
  170. }
  171.  
  172. void
  173. animate(void)
  174. {
  175.   tick();
  176.   glutPostRedisplay();
  177. }
  178.  
  179. void
  180. visible(int state)
  181. {
  182.   if (state == GLUT_VISIBLE) {
  183.     if (moving)
  184.       glutIdleFunc(animate);
  185.   } else {
  186.     if (moving)
  187.       glutIdleFunc(NULL);
  188.   }
  189. }
  190.  
  191. /* ARGSUSED1 */
  192. void
  193. keyboard(unsigned char ch, int x, int y)
  194. {
  195.   switch (ch) {
  196.   case ' ':
  197.     if (!moving) {
  198.       tick();
  199.       glutPostRedisplay();
  200.     }
  201.     break;
  202.   case 27:             /* ESC */
  203.     exit(0);
  204.     break;
  205.   }
  206. }
  207.  
  208. #define ADD_PLANE    1
  209. #define REMOVE_PLANE    2
  210. #define MOTION_ON    3
  211. #define MOTION_OFF    4
  212. #define QUIT        5
  213.  
  214. void
  215. menu(int item)
  216. {
  217.   switch (item) {
  218.   case ADD_PLANE:
  219.     add_plane();
  220.     break;
  221.   case REMOVE_PLANE:
  222.     remove_plane();
  223.     break;
  224.   case MOTION_ON:
  225.     moving = GL_TRUE;
  226.     glutChangeToMenuEntry(3, "Motion off", MOTION_OFF);
  227.     glutIdleFunc(animate);
  228.     break;
  229.   case MOTION_OFF:
  230.     moving = GL_FALSE;
  231.     glutChangeToMenuEntry(3, "Motion", MOTION_ON);
  232.     glutIdleFunc(NULL);
  233.     break;
  234.   case QUIT:
  235.     exit(0);
  236.     break;
  237.   }
  238. }
  239.  
  240. int
  241. main(int argc, char *argv[])
  242. {
  243.   glutInit(&argc, argv);
  244.   /* use multisampling if available */
  245.   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE);
  246.   glutCreateWindow("glutplane");
  247.   glutDisplayFunc(draw);
  248.   glutKeyboardFunc(keyboard);
  249.   glutVisibilityFunc(visible);
  250.   glutCreateMenu(menu);
  251.   glutAddMenuEntry("Add plane", ADD_PLANE);
  252.   glutAddMenuEntry("Remove plane", REMOVE_PLANE);
  253.   glutAddMenuEntry("Motion", MOTION_ON);
  254.   glutAddMenuEntry("Quit", QUIT);
  255.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  256.   /* setup OpenGL state */
  257.   glClearDepth(1.0);
  258.   glClearColor(0.0, 0.0, 0.0, 0.0);
  259.   glMatrixMode(GL_PROJECTION);
  260.   glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 20);
  261.   glMatrixMode(GL_MODELVIEW);
  262.   /* add three initial random planes */
  263.   srandom(getpid());
  264.   add_plane();
  265.   add_plane();
  266.   add_plane();
  267.   /* start event processing */
  268.   glutMainLoop();
  269.   return 0;             /* ANSI C requires main to return int. */
  270. }
  271.